package com.example.alternateThread.vol;

public class AlternateThread extends Thread {
    private static volatile int i = 0;
    private static volatile int flag = 0;
    private final int num;

    public AlternateThread(int num) {
        this.num = num;
    }

    @Override
    public void run() {
        while (i < 100) {
            if (num == flag) {
                System.out.println("线程" + num + "打印：" + i++);
                flag = (flag + 1) % 3;
            }
        }
    }

    public static void main(String[] args) {
        AlternateThread thread0 = new AlternateThread(0);
        AlternateThread thread1 = new AlternateThread(1);
        AlternateThread thread2 = new AlternateThread(2);
        thread0.start();
        thread1.start();
        thread2.start();
    }
}
// volatile只能保证可见性，无法保证原子性，所以对于i++或者i=i+1这类的操作，volatile无法保证i的原子性了，但是这里又使用了一个flag变量，这个量也用volatile进行了修饰，用flag控制if判断里面的代码是否被执行，
// 相当于用flag保证了原子性，当一个线程修改了flag变量的时候，其他线程是无法执行if判断里面的代码的，只能当相应的线程把flag修改回之后，下个线程才能执行if里面的代码块。可以把flag看成一个“锁”。